import { Request, Response } from 'express';
import { intersection } from 'lodash';
import * as fs from 'fs';
import { isEmpty } from './utils';
import dayjs from 'dayjs';
import { getMuneData } from './menu';

const getAccessUser = () => {
  const currentRecordStr = fs.readFileSync('./mock/database/currentRecord.json', 'utf-8');
  const currentRecord = currentRecordStr ? JSON.parse(currentRecordStr) : null;
  if (currentRecord === null) return false;
  if (Object.keys(currentRecord.currentUser).length > 0) {
    return currentRecord.currentUser;
  }
  return false;
};

const toUpperStr = (str: string) => str.toUpperCase();

const getCurrentUserMenuPath = (treeData: MENU.MenuType[], hasMenuIds: string[]) => {
  return treeData.reduce((result, cur) => {
    if (hasMenuIds.includes(cur.id)) {
      result[toUpperStr(cur.link)] = true;
    }
    if (cur.children && cur.children.length > 0) {
      if (cur.children.some((item) => hasMenuIds.includes(item.id))) {
        result[toUpperStr(cur.link)] = true;
      }
      Object.assign(result, getCurrentUserMenuPath(cur.children, hasMenuIds));
    }

    return result;
  }, {});
};

// 代码中会兼容本地 service mock 以及部署站点的静态数据
export default {
  // 支持值为 Object 和 Array
  'GET /api/currentUser': (req: Request, res: Response) => {
    const currentUser: SYSTEMUSER.UserType = getAccessUser();
    if (!currentUser) {
      res.status(401).send({
        data: {
          isLogin: false,
        },
        errorCode: '401',
        errorMessage: '请先登录！',
        success: true,
      });
      return;
    }
    const authMenuRecordStr = fs.readFileSync('./mock/database/authMenuRecord.json', 'utf-8');
    const authMenuRecord = authMenuRecordStr ? JSON.parse(authMenuRecordStr) : {};
    const { menuTree } = getMuneData();
    const authMenuIdArr = authMenuRecord[currentUser.systemRole] ?? [];
    res.send({
      success: true,
      data: {
        ...currentUser,
        authMenuIdArr,
        authMenuTree: getCurrentUserMenuPath(menuTree, authMenuIdArr),
      },
    });
  },
  'POST /api/login/account': async (req: Request, res: Response) => {
    const { userPassword, userName } = req.body;
    const userListStr = fs.readFileSync('./mock/database/users.json', 'utf-8');
    const userList: SYSTEMUSER.UserType[] = userListStr ? JSON.parse(userListStr) : [];
    const currentUser = userList.find(
      (item) => item.userName === userName && item.userPassword === userPassword,
    );
    const currentRecordStr = fs.readFileSync('./mock/database/currentRecord.json', 'utf-8');
    const currentRecord = currentRecordStr ? JSON.parse(currentRecordStr) : {};
    if (currentUser) {
      currentRecord.currentUser = currentUser;
      fs.writeFileSync('./mock/database/currentRecord.json', JSON.stringify(currentRecord));
      res.send({
        success: true,
        data: {
          accessToken: dayjs().valueOf().toString(16),
        },
      });
    } else {
      res.send({
        data: null,
        errorMessage: '用户名或密码错误！',
        success: false,
      });
    }
  },
  'POST /api/login/outLogin': (req: Request, res: Response) => {
    const currentRecordStr = fs.readFileSync('./mock/database/currentRecord.json', 'utf-8');
    const currentRecord = currentRecordStr ? JSON.parse(currentRecordStr) : {};
    currentRecord.currentUser = {};
    fs.writeFileSync('./mock/database/currentRecord.json', JSON.stringify(currentRecord));
    res.send({ data: {}, success: true });
  },
  'GET /api/500': (req: Request, res: Response) => {
    res.status(500).send({
      timestamp: dayjs().valueOf(),
      status: 500,
      error: 'error',
      message: 'error',
    });
  },
  'GET /api/404': (req: Request, res: Response) => {
    res.status(404).send({
      timestamp: dayjs().valueOf(),
      status: 404,
      error: 'Not Found',
      message: 'Not Found',
    });
  },
  'GET /api/403': (req: Request, res: Response) => {
    res.status(403).send({
      timestamp: dayjs().valueOf(),
      status: 403,
      error: 'Forbidden',
      message: 'Forbidden',
    });
  },
  'GET /api/401': (req: Request, res: Response) => {
    res.status(401).send({
      timestamp: dayjs().valueOf(),
      status: 401,
      error: 'Unauthorized',
      message: 'Unauthorized',
    });
  },
  'GET /api/userList': (req: Request, res: Response) => {
    console.log('请求参数 mock/user.ts', req.query);
    const { current, pageSize, userName } = req.query as unknown as SYSTEMUSER.UserParams;
    const userListStr = fs.readFileSync('./mock/database/users.json', 'utf-8');
    if (!userListStr) {
      res.send({
        success: true,
        data: {
          list: [],
          hasNextPage: false,
          current,
          pageSize,
        },
      });
      return;
    }

    let resUsers: SYSTEMUSER.UserType[] = [];
    const userList: SYSTEMUSER.UserType[] = JSON.parse(userListStr);
    let total = userList.length;
    if (!isEmpty(userList)) {
      if (userName) {
        const tempList = userList.filter((user) => {
          return intersection([...user.userName], [...userName]).length > 0;
        });
        total = tempList.length;
        resUsers = tempList.slice((current - 1) * pageSize, current * pageSize);
      } else {
        resUsers = userList.slice((current - 1) * pageSize, current * pageSize);
      }
      res.send({
        success: true,
        data: {
          list: resUsers,
          hasNextPage: total > current * pageSize,
          current,
          pageSize,
          total,
        },
      });
    } else {
      res.send({
        success: true,
        data: {
          list: [],
          hasNextPage: false,
          current,
          pageSize,
          total: 0,
        },
      });
    }
  },
  'GET /api/user': (req: Request, res: Response) => {
    console.log('请求参数 mock/user.ts', req.query);
    const { id, userName } = req.query as unknown as SYSTEMUSER.UserInfoParams;
    const userListStr = fs.readFileSync('./mock/database/users.json', 'utf-8');
    const userList: SYSTEMUSER.UserType[] = userListStr ? JSON.parse(userListStr) : [];
    let currentUser: SYSTEMUSER.UserType | undefined;
    if (isEmpty(id) && isEmpty(userName)) {
      res.send({
        data: null,
        errorMessage: '用户id或用户名不可为空！',
        success: false,
      });
      return;
    }

    if (id) {
      currentUser = userList.find((item) => item.id === id);
      res.send({
        success: true,
        data: currentUser,
      });
      return;
    }

    if (userName) {
      currentUser = userList.find((item) => item.userName === userName);
      res.send({
        success: true,
        data: currentUser,
      });
      return;
    }
  },
  'POST /api/user': (req: Request, res: Response) => {
    console.log('请求参数 mock/user.ts', req.body);
    const { userPassword, systemRole, userName } = req.body as unknown as SYSTEMUSER.AddRoleParams;
    if (!userName) {
      res.send({
        data: null,
        errorMessage: '用户名不可为空！',
        success: false,
      });
      return;
    }
    if (!userPassword) {
      res.send({
        data: null,
        errorMessage: '用户密码不可为空！',
        success: false,
      });
      return;
    }
    if (!systemRole) {
      res.send({
        data: null,
        errorMessage: '授权角色不可为空！',
        success: false,
      });
      return;
    }
    const userListStr = fs.readFileSync('./mock/database/users.json', 'utf-8');
    const userList: SYSTEMUSER.UserType[] = userListStr ? JSON.parse(userListStr) : [];
    const hasSameName = userList.some((item) => item.userName === userName);
    if (hasSameName) {
      res.send({
        data: null,
        errorMessage: '该用户名已存在',
        success: false,
      });
      return;
    }
    userList.push({
      userName,
      userPassword,
      systemRole,
      createTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
      id: `user${dayjs().valueOf()}`,
    });
    fs.writeFileSync('./mock/database/users.json', JSON.stringify(userList));
    res.send({
      success: true,
      data: [],
    });
  },
  'PUT /api/user': (req: Request, res: Response) => {
    console.log('请求参数 mock/user.ts', req.body);
    const { id, systemRole, userName } = req.body as unknown as SYSTEMUSER.EditRoleParams;
    if (!id) {
      res.send({
        data: null,
        errorMessage: '用户id不可为空！',
        success: false,
      });
      return;
    }
    if (!userName) {
      res.send({
        data: null,
        errorMessage: '用户名不可为空！',
        success: false,
      });
      return;
    }
    if (!systemRole) {
      res.send({
        data: null,
        errorMessage: '授权角色不可为空！',
        success: false,
      });
      return;
    }
    const userListStr = fs.readFileSync('./mock/database/users.json', 'utf-8');
    const userList: SYSTEMUSER.UserType[] = userListStr ? JSON.parse(userListStr) : [];
    const hasSameName = userList.some((item) => item.userName === userName);
    if (hasSameName) {
      res.send({
        data: null,
        errorMessage: '该用户名已存在',
        success: false,
      });
      return;
    }
    const editUser = userList.find((item) => item.id === id);
    if (!editUser) {
      res.send({
        data: null,
        errorMessage: '当前编辑用户不存在！',
        success: false,
      });
      return;
    }
    Object.assign(editUser, { userName, systemRole });
    fs.writeFileSync('./mock/database/users.json', JSON.stringify(userList));
    res.send({
      success: true,
      data: [],
    });
  },
  'DELETE /api/user': (req: Request, res: Response) => {
    console.log('请求参数 mock/user.ts', req.query);
    const { id } = req.query as unknown as { id: string };
    if (!id) {
      res.send({
        data: null,
        errorMessage: '用户id不可为空！',
        success: false,
      });
      return;
    }
    const userListStr = fs.readFileSync('./mock/database/users.json', 'utf-8');
    const userList: SYSTEMUSER.UserType[] = userListStr ? JSON.parse(userListStr) : [];
    const delIndex = userList.findIndex((item) => item.id === id);
    if (delIndex > -1) {
      userList.splice(delIndex, 1);
      fs.writeFileSync('./mock/database/users.json', JSON.stringify(userList));
      res.send({
        success: true,
        data: [],
      });
    } else {
      res.send({
        data: null,
        errorMessage: '该用户不存在！',
        success: false,
      });
    }
  },
};
